package com.woniu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.commons.exception.YogaException;
import com.woniu.commons.model.RedisKey;
import com.woniu.commons.model.StateData;
import com.woniu.util.OSSUtil;
import com.woniu.commons.util.RedisUtil;
import com.woniu.dao.mapper.YGoodsMapper;
import com.woniu.model.model.YGoods;
import com.woniu.model.param.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.service.YGoodsService;
import io.seata.spring.annotation.GlobalTransactional;
import org.aspectj.weaver.ast.Var;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Objects;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 吴彦祖
 * @since 2024年05月23日
 */
@Service
public class YGoodsServiceImpl extends ServiceImpl<YGoodsMapper, YGoods> implements YGoodsService {

    @Resource
    private YGoodsMapper goodsMapper;
    @Resource
    private RedisUtil redisUtil;


    /**
     * 新增商品
     *
     * @param param form:goodsName;商品名
     *              goodsPrice;商品价格
     *              goodsNum;商品数量
     * @return
     * @throws Exception
     */
    @Override
    @GlobalTransactional(rollbackFor = Throwable.class)
    public void InsertBookInfo(GoodsInsertParam param) throws YogaException {
//        try {
        if (param.getGoodsPrice().compareTo(BigDecimal.ZERO) <= 0) {
            //compareTo 方法用来比较BigDecimal类型    返回三个可能的值：-1（小于）、0（等于）、1（大于）
            throw new YogaException(500, "输入价格有误，请重新输入");
        }
        if (param.getGoodsNum() <= 0) {
            throw new YogaException(500, "输入数量有误，请重新输入");
        }
        YGoods yGoods = BeanUtil.toBean(param, YGoods.class);
        yGoods.setGoodsState(StateData.GOODS_TYPE_STATE_DELIST);//新增的商品状态给成下架，后面再点上架商品
        yGoods.setGoodsFrooze(0);//冻结量给0
        goodsMapper.insert(yGoods);
//        } catch (Exception e) {
//            //一旦报错，就把阿里云上的文件删除掉
//            OSSUtil.deleteFile("hugedehome", FileUtil.getName(param.getGoodsImage()));
//            throw e;//让AOP还是能拿到异常，做回滚
//        }
    }

    /**
     * 修改商品图片
     *
     * @param param
     * @return
     * @throws Exception
     */
    @Override
    @GlobalTransactional(rollbackFor = Throwable.class)
    public void updateimage(GoodsUpdataImageParam param) throws YogaException {


        try {
            YGoods yGoods = goodsMapper.selectById(param.getGoodsId());
            if (yGoods == null) {
                throw new YogaException(500, "该商品不存在");
            }
            if (Objects.equals(yGoods.getGoodsState(), StateData.GOODS_TYPE_STATE_DELIST)) {
                throw new YogaException(500, "该商品已下架");
            }
            yGoods.setGoodsImage(param.getGoodsImage());
            goodsMapper.updateById(yGoods);
        } catch (YogaException e) {
            //一旦报错，就把阿里云新上传的文件删除掉
            OSSUtil.deleteFile("hugedehome", FileUtil.getName(param.getGoodsImage()));
            System.out.println("进入了catch");
            throw e;//让AOP还是能拿到异常，做回滚
        }
    }


    /**
     * 修改商品信息
     *
     * @param param //商品id goodsId;
     *              //商品名 goodsName;
     *              //商品价格 goodsPrice;
     *              //商品数量 goodsNum;
     * @return
     * @throws YogaException
     */
    @Override
    public void updateGoodsMessage(GoodsUpdataMessageParam param) throws YogaException {
        YGoods yGoods = goodsMapper.selectById(param.getGoodsId());
        if (yGoods == null) {
            throw new YogaException(500, "修改商品不存在");
        }
        if (yGoods.getGoodsNum() < 0) {
            throw new YogaException(500, "输入数量有误");
        }
        if (param.getGoodsPrice().compareTo(BigDecimal.ZERO) == 0) {
            throw new YogaException(500, "输入价格有误，请重新输入");
        }
        yGoods.setGoodsName(param.getGoodsName());
        yGoods.setGoodsNum(param.getGoodsNum());
        yGoods.setGoodsPrice(param.getGoodsPrice());

        goodsMapper.updateById(yGoods);
    }

    /**
     * 分页查询
     *
     * @param param pageNum;pageSize;
     * @return
     * @throws YogaException
     */
    @Override
    public Page<YGoods> loadPageGoods(PageParam param) throws YogaException {

        if (param.getPageNum() == null) {
            param.setPageNum(1);
        }
        if (param.getPageSize() == null) {
            param.setPageSize(5);
        }

        //拼接条件
        QueryWrapper<YGoods> wrapper = new QueryWrapper<YGoods>();

        return baseMapper.selectPage(new Page<YGoods>(param.getPageNum(), param.getPageSize()), wrapper);
    }

    /**
     * 下架商品
     *
     * @param goodsId：商品id
     * @return
     * @throws YogaException
     */
    @Override
    public void disable(Integer goodsId) throws YogaException {
        YGoods yGoods = goodsMapper.selectById(goodsId);
        if (yGoods == null) {
            throw new YogaException(500, "下架商品不存在");
        }
        if (Objects.equals(yGoods.getGoodsState(), StateData.GOODS_TYPE_STATE_DELIST)) {
            throw new YogaException(500, "商品状态有误");
        }
        yGoods.setGoodsState(StateData.GOODS_TYPE_STATE_DELIST);
        goodsMapper.updateById(yGoods);
    }

    /**
     * 上架商品
     *
     * @param goodsId：商品id
     * @return
     * @throws YogaException
     */
    @Override
    public void enable(Integer goodsId) throws YogaException {
        YGoods yGoods = goodsMapper.selectById(goodsId);
        if (yGoods == null) {
            throw new YogaException(500, "上架商品不存在");
        }
        if (Objects.equals(yGoods.getGoodsState(), StateData.GOODS_TYPE_STATE_STARE)) {
            throw new YogaException(500, "商品状态已是上架中，请勿重复提交");
        }
        yGoods.setGoodsState(StateData.GOODS_TYPE_STATE_STARE);
        goodsMapper.updateById(yGoods);
    }

    /**
     * 传一个对象，根据id去修改里面的信息
     * 在商城订单里面用了，用于去修改商品的冻结量和数量
     *
     * @param ygoods 商品对象
     * @return
     * @throws YogaException
     */
    @Override
    public void updateByIdGoods(YGoods ygoods) throws YogaException {
        goodsMapper.updateById(ygoods);
    }

    /**
     * 添加商品到我的购物车
     *
     * @param ：商品id 数量 用户id
     * @return
     * @throws YogaException
     */
    @Override
    public void addShoppingCar(AddShoppingCarParam param) throws YogaException {
        //1.先判断商品是否正常
        YGoods yGoods = baseMapper.selectById(param.getGoodSId());
        if (yGoods == null) {
            throw new YogaException(500, "商品不存在");
        }
        if (yGoods.getGoodsNum() < 0) {
            throw new YogaException(500, "商品数量不足");
        }
        if (!Objects.equals(yGoods.getGoodsState(), StateData.GOODS_STATE_START)) {
            throw new YogaException(500, "商品状态有误");
        }

        //2.再判断该用户的购物车里面是否有这个商品了
        if (redisUtil.zscore(RedisKey.userShopping(param.getUserId()), param.getGoodSId() + "") == null) {
            //如果是null说明购物车里面没有这个商品
            redisUtil.zsetAdd(RedisKey.userShopping(param.getUserId()), param.getGoodSId() + "", System.currentTimeMillis());
            //System.currentTimeMillis()是 Java 中的一个静态方法，用于获取当前时间的毫秒数。
//            try {
                System.out.println("进添加了");
            System.out.println(yGoods.toString()+"+++");
            System.out.println(yGoods.getGoodsId());
            System.out.println(yGoods.getGoodsName());
            System.out.println(yGoods.getGoodsPrice());
            System.out.println(yGoods.getGoodsPrice());
            System.out.println(yGoods.getGoodsImage());
            System.out.println(param.getNumber());
                //向redis中新增一个hash数据，保存完整的购物信息
                HashMap<String, Object> map = new HashMap<>();
                map.put("GoodsId", yGoods.getGoodsId() + "");
                map.put("GoodsName", yGoods.getGoodsName());
                map.put("GoodsPrice", yGoods.getGoodsPrice().toString());
                map.put("GoodsImage", yGoods.getGoodsImage());
                map.put("GoodsNumber", param.getNumber() + "");

                redisUtil.hmset(RedisKey.shoppingInfo(param.getUserId(), param.getGoodSId()), map);
                System.out.println("添加完");
//            } catch (YogaException e) {
//                redisUtil.zsetRemove(RedisKey.userShopping(param.getUserId()), param.getGoodSId() + "");
//                throw e;
//            }
        } else {
            //不是null，购物车里面有这个商品
            //让购物车+1
            System.out.println("进了++1的else");
            redisUtil.hincrby(RedisKey.shoppingInfo(param.getUserId(), param.getGoodSId()), param.getNumber());
        }


    }

    /**
     * 删除我的购物车里面的商品
     * GoodSId：商品id
     * number：数量
     * token：用户id
     *
     * @return
     * @throws YogaException
     */
    @Override
    public void delShoppingCar(AddShoppingCarParam param) throws YogaException {
        //1.先判断商品是否正常
        YGoods yGoods = baseMapper.selectById(param.getGoodSId());
        if (yGoods == null) {
            throw new YogaException(500, "商品不存在");
        }
        //判断当前用户得购物车列表存不存在这个商品
        if (redisUtil.zscore(RedisKey.userShopping(param.getUserId()), param.getGoodSId() + "") != null) {
            redisUtil.zsetRemove(RedisKey.userShopping(param.getUserId()), param.getGoodSId() + "");
            redisUtil.delete(RedisKey.shoppingInfo(param.getUserId(), param.getGoodSId()));
        } else {
            throw new YogaException(500, "购物车还没该商品");
        }


    }


    /**
     * 修改购物车里面商品的数量
     * param   goodsId;商品id
     * userId;用户id
     * number;修改的数量
     *
     * @param
     * @return
     * @throws YogaException
     */
    @Override
    public void changShoppingCarNumber(ChangShoppingCarNumberParam param) throws YogaException {
        //1.先判断商品是否正常
        YGoods yGoods = baseMapper.selectById(param.getGoodsId());
        if (yGoods == null) {
            throw new YogaException(500, "商品不存在");
        }
        if (yGoods.getGoodsState() != StateData.GOODS_STATE_START) {
            throw new YogaException(500, "商品状态有误，请移除购物车");
        }
        if (param.getNumber() < 0) {
            throw new YogaException(500, "数量有误，请重新输入");
        }
        //执行修改
        redisUtil.hset(RedisKey.shoppingInfo(param.getUserId(), param.getGoodsId()), "GoodsNumber", param.getNumber());
    }


}
